Overview
Fetches the latest daily price band changes (circuit limit revisions) from NSE Archives. The script checks the last 7 days backwards from today to find the most recent CSV file, as NSE does not publish these files on weekends or holidays.
Source: fetch_incremental_price_bands.py
Phase: Phase 2 (Enrichment)
Output: incremental_price_bands.json
Data Source
NSE Archives CSV Endpoint
GET https://nsearchives.nseindia.com/content/equities/eq_band_changes_{date}.csv
Date in ddmmyyyy format (e.g., 03032024 for March 3, 2024)
Example URL
https://nsearchives.nseindia.com/content/equities/eq_band_changes_03032024.csv
The NSE CSV contains the following structure (example):
Symbol,Series,Date,New Band,Old Band,Applicable Date
RELIANCE,EQ,03-MAR-2024,10,20,04-MAR-2024
TATASTEEL,EQ,03-MAR-2024,20,10,04-MAR-2024
Function Signature
def fetch_nse_price_bands():
"""
Fetches the latest price band changes CSV from NSE Archives.
Searches backwards up to 7 days to find the most recent file.
Parses CSV using pandas and saves as JSON.
"""
Date Search Logic
Searches backwards from today up to 7 days:
today = datetime.now()
clean_data = []
for i in range(8): # 0-7 days back
check_date = today - timedelta(days=i)
date_str = check_date.strftime("%d%m%Y") # Format: ddmmyyyy
url = base_url.format(date=date_str)
response = requests.get(url, headers=headers, timeout=10)
if response.status_code == 200:
# Found the file, parse and break
break
CSV Parsing
Uses pandas for robust CSV parsing:
csv_content = response.content.decode('utf-8')
df = pd.read_csv(io.StringIO(csv_content))
# Convert to list of dictionaries
raw_data = df.to_dict(orient='records')
# Clean whitespace from keys and values
for record in raw_data:
cleaned_record = {}
for k, v in record.items():
key = k.strip() if isinstance(k, str) else k
value = v.strip() if isinstance(v, str) else v
cleaned_record[key] = value
clean_data.append(cleaned_record)
Output Structure
Series type (typically “EQ” for equity)
Date of band change announcement
New circuit limit percentage
Previous circuit limit percentage
Date when new band becomes effective
Example Output
[
{
"Symbol": "RELIANCE",
"Series": "EQ",
"Date": "03-MAR-2024",
"New Band": "10",
"Old Band": "20",
"Applicable Date": "04-MAR-2024"
},
{
"Symbol": "TATASTEEL",
"Series": "EQ",
"Date": "03-MAR-2024",
"New Band": "20",
"Old Band": "10",
"Applicable Date": "04-MAR-2024"
}
]
Dependencies
requests — HTTP client for downloading CSV
json — JSON serialization
datetime — Date calculations
pandas — CSV parsing and data manipulation
io — In-memory file handling for CSV parsing
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
"Accept": "*/*"
}
Error Handling
- 10-second timeout per HTTP request
- Gracefully handles 404 (file not found) for non-trading days
- Continues searching backwards through date range
- Reports parse errors but continues to next date
if response.status_code == 200:
print(f" Found data for {date_str}!")
# Parse and break
elif response.status_code == 404:
print(f" No file found for {date_str} (404).")
else:
print(f" Unexpected status {response.status_code} for {date_str}.")
Usage Example
python3 fetch_incremental_price_bands.py
Expected Output:
Checking for price band changes on 03032024...
Found data for 03032024!
Successfully saved 15 price band changes to incremental_price_bands.json
On Weekend/Holiday:
Checking for price band changes on 03032024...
No file found for 03032024 (404).
Checking for price band changes on 02032024...
No file found for 02032024 (404).
Checking for price band changes on 01032024...
Found data for 01032024!
Successfully saved 12 price band changes to incremental_price_bands.json
Integration
This script is part of Phase 2 (Enrichment) in the EDL Pipeline. The output file is consumed by:
add_corporate_events.py — Adds ”#: +/- Revision” event markers for price band changes
bulk_market_analyzer.py — Updates the “Circuit Limit” field
Run via master pipeline:
python3 run_full_pipeline.py
Data Availability Notes
- NSE typically publishes this file on trading days only
- File is usually available after market close (3:30 PM IST)
- Weekends and holidays will have no file (404 response)
- The 7-day search window ensures catching the latest file even after long weekends
Field Interpretation
Band Meanings:
2% — Very high surveillance/volatility
5% — High surveillance
10% — Moderate surveillance
20% — Normal (standard circuit limit)
Lower band values indicate tighter restrictions and higher regulatory scrutiny.